package com.talent.service.iot.mqtt.model.fix;

import io.netty.handler.codec.mqtt.MqttMessageType;
import io.netty.handler.codec.mqtt.MqttQoS;

/**
 * @Author: hszhou
 * @Date: 2024/11/25 11:08
 * @Description: mqtt的固定头部信息
 */

public class TlMqttFixedHead {


    /**消息类型*/
    private MqttMessageType messageType;
    /**重发标志位 0 是新消息  1肯能是重发*/
    private boolean dup;
    /**qos的等级*/
    private MqttQoS qos;
    /**是否保留消息*/
    private boolean retain;
    /**消息长度*/
    private int length;


    public MqttMessageType getMessageType() {
        return messageType;
    }

    public void setMessageType(MqttMessageType messageType) {
        this.messageType = messageType;
    }

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public boolean getDup() {
        return dup;
    }

    public void setDup(boolean dup) {
        this.dup = dup;
    }

    public MqttQoS getQos() {
        return qos;
    }

    public void setQos(MqttQoS qos) {
        this.qos = qos;
    }

    public boolean getRetain() {
        return retain;
    }

    public void setRetain(boolean retain) {
        this.retain = retain;
    }


    public static TlMqttFixedHead of(MqttMessageType messageType,MqttQoS qos,boolean retain){
        TlMqttFixedHead fixedHead = new TlMqttFixedHead();
        fixedHead.setDup(false);
        fixedHead.setMessageType(messageType);
        fixedHead.setQos(qos);
        fixedHead.setRetain(retain);
        return fixedHead;
    }

    public static TlMqttFixedHead of(MqttMessageType messageType,MqttQoS qos,boolean dup,boolean retain){
        TlMqttFixedHead fixedHead = new TlMqttFixedHead();
        fixedHead.setDup(dup);
        fixedHead.setMessageType(messageType);
        fixedHead.setQos(qos);
        fixedHead.setRetain(retain);
        return fixedHead;
    }

    public static TlMqttFixedHead of(MqttMessageType messageType){
        TlMqttFixedHead fixedHead = new TlMqttFixedHead();
        fixedHead.setDup(false);
        fixedHead.setMessageType(messageType);
        fixedHead.setQos(MqttQoS.AT_MOST_ONCE);
        fixedHead.setRetain(false);
        return fixedHead;
    }

    @Override
    public String toString() {
        return "TlMqttFixedHead{" +
              //  "type=" + type +
                ", messageType=" + messageType +
                ", length=" + length +
                ", dup=" + dup +
                ", qos=" + qos +
                ", retain=" + retain +
                '}';
    }



    /**
     * 计算固定报头第一字节
     *
     * @param header
     * @return
     */
//    private static int getFixedHeaderByte1(MqttFixedHeader header) {
//        int ret = 0;
//        // 1. 将消息类型左移四位，因为第一字节的0-3位为类型对应的标志位
//        ret |= header.messageType().value() << 4;
//
//        // 2. 如果是重发报文，则重发标志为1，第一字节的第3位
//        if (header.isDup()) {
//            // 采用或运算，将第一字节的第三位这只为1
//            ret |= 0x08;
//        }
//        // 3. Qos等级为第一字节的第1、2位
//        ret |= header.qosLevel().value() << 1;
//
//        // 4.如果要保留消息，则保留标志为1，第一字节的第0位
//        if (header.isRetain()) {
//            ret |= 0x01;
//        }
//        return ret;
//    }

    /**
     * 写入固定报头中的剩余长度字段
     *
     * @param buf
     * @param num
     */
//    private static void writeVariableLengthInt(ByteBuf buf, int num) {
//        do {
//            // 1. %求余，取前一个字节所表示的数值大小，
//            // 比如num表示200字节，第一次这里digit表示72
//            // 由于第二次，num=1,大于0成立，这里1 % 128 = 1
//            int digit = num % 128;
//            // 2. 第一除以128,即去除前一个字节，num表示1，第二次等于0了，表示没有字节了
//            num /= 128;
//            if (num > 0) {
//                // 3.如果还有字节，则最高位进制位设置为1
//                digit |= 0x80;
//            }
//            // 4. 第一字节写入72，第二字节写入1
//            buf.writeByte(digit);
//        } while (num > 0);
//    }

    /**
     * 通过或运算计算连接标志
     */
//    private static int getConnVariableHeaderFlag(MqttConnectVariableHeader variableHeader) {
//        int flagByte = 0;
//        if (variableHeader.hasUserName()) {
//            flagByte |= 0x80;
//        }
//        if (variableHeader.hasPassword()) {
//            flagByte |= 0x40;
//        }
//        if (variableHeader.isWillRetain()) {
//            flagByte |= 0x20;
//        }
//        flagByte |= (variableHeader.willQos() & 0x03) << 3;
//        if (variableHeader.isWillFlag()) {
//            flagByte |= 0x04;
//        }
//        if (variableHeader.isCleanSession()) {
//            flagByte |= 0x02;
//        }
//        return flagByte;
//    }
}
